import { nextTick, onBeforeUnmount, onMounted } from 'vue'
import type { Ref } from 'vue'

type IntervalHandle = ReturnType<typeof setInterval>

// eslint-disable-next-line
function sleep (ms: number) {
  const start = Date.now()
  let end = start
  while (end - start <= ms) {
    end = Date.now()
  }
}

export default function useSimpleMove(
  wrapRef: Ref<HTMLElement | null>,
  lists: Ref<any[]>,
  option?: Partial<{
    speed: number
    orient: string
    per: number
    gap: number
  }>,
) {
  let timer: IntervalHandle

  const defaultOption = {
    speed: 1000,
    orient: 'vertical',
    per: 30,
    gap: 5,
  }

  const o = {
    ...defaultOption,
    ...option,
  }
  const { speed, orient, per, gap } = o

  async function animate() {
    const item = toValue(lists).shift()
    await nextTick()
    lists.value.push(item)
  }

  const moveable = computed(() => {
    const wrapElem = toValue(wrapRef)
    if (!wrapElem)
      return false

    const containerElem = wrapElem.parentNode

    if (containerElem) {
      const property = orient === 'horizontal' ? 'width' : 'height'
      const wrapOffset = (per + gap) * toValue(lists).length
      const containerOffset = (containerElem as HTMLElement).getBoundingClientRect()[property]

      // console.log(wrapOffset, containerOffset)
      return wrapOffset > containerOffset
    }
    return false
  })

  function pause() {
    if (toValue(moveable)) {
      timer && clearInterval(timer)
    }
  }

  function play() {
    if (toValue(moveable)) {
      timer = setInterval(() => {
        animate()
      }, speed)
    }
  }

  onMounted(() => {
    play()
  })

  onBeforeUnmount(() => {
    pause()
  })

  return {
    pause,
    play,
  }
}
